import secrets
from ast import literal_eval

from fastapi import APIRouter, Request, Cookie, Request, HTTPException
from fastapi.responses import StreamingResponse
from fastapi.logger import logger
from tortoise.expressions import Q
from complex_captcha import gen_captcha

import models
from ext import redis

router = APIRouter()


@router.post("/ajax/process.aspx")
async def opotions(request: Request):
    form = await request.form()
    key = form.get('value')
    name = 'opotions'
    value = await redis.client.hget(name, key)
    if value:
        return literal_eval(value)
    raise HTTPException(400)


@router.get("/ajax/checkcode.ashx", summary='图片验证码')
async def image_captcha():
    image, text = gen_captcha(byte_stream=True)
    sessionid = secrets.token_urlsafe(20)
    ret = f'{sessionid} {text}'
    logger.info(ret)
    name = f'sessionid:{sessionid}'
    await redis.client.set(name, text.lower(), 3600 * 3)
    response = StreamingResponse(content=image, media_type='image/jpeg')
    response.set_cookie(key='sessionid', value=sessionid)
    return response


submit_map = {'3': [models.StaffMember, models.StaffMemberIn],
              '4': [models.Guest, models.GuestIn],
              '5': [models.Exhibitor, models.ExhibitorIn],
              '6': [models.Volunteer, models.VolunteerIn],
              '7': [models.Constructor, models.ConstructorIn],
              '8': [models.Other, models.OtherIn]
              }


@router.get("/ajax/only.aspx")
async def only(formid: str, fieldid: str, onlyvalue: str):
    model = submit_map[formid][0]
    exist = await model.filter(**{fieldid: onlyvalue}).exists()
    if exist:
        return 1
    return 0


def get_form(data):
    activity_values = []
    form = {}
    for k, v in data.multi_items():
        if v:
            if k == 'activity':
                activity_values.append(v)
            form[k] = v.strip()
    if activity_values:
        form['activity'] = str(activity_values)
    return form


@router.post("/ajax/formsubmit.aspx")
async def sign_up(submitid: str, request: Request, sessionid: str = Cookie()):
    data = await request.form()
    form = get_form(data)
    model, schema = submit_map[submitid]
    # print('data', data)
    # print('form', form)

    check_code = form.pop('reserve').lower()
    name = f'sessionid:{sessionid}'
    origin_code = await redis.client.get(name)
    await redis.client.delete(name)
    # print('origin_code', origin_code)
    # print('check_code', check_code)
    if origin_code != check_code:
        return {'type': '0', 'msg': '验证码错误'}

    identity = form['identity']
    phone = form['phone']
    exist = await model.filter(Q(identity=identity) | Q(phone=phone)).exists()
    if exist:
        return {'type': '0', 'msg': '身份证或电话已被使用'}

    item = schema(**form)
    await model.create(**item.dict())
    return {'type': '1', 'msg': '提交成功', 'returnurl': 'http://192.168.115.115:88//index.html'}
